
#include <stdio.h>
#include <string.h> 
#include "uart.h"
#include "dma.h"
#include "hc32_ll_clk.h"
#include "hc32_ll_utility.h"
#include "hc32_ll_usart.h"
#include "hc32_common.h"
 
 
#define USART_BAUDRATE                  (115200ul)		
/***************************************usart1***************************************************/
/* USART unit definition */
#define USART1_UNIT						(CM_USART1)
#define USART1_FCG_ENABLE()				(FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USART1, ENABLE))
/* USART RX Port/Pin definition */
#define USART1_RX_PORT					(GPIO_PORT_A)//(PortC)//(PortA)
#define USART1_RX_PIN					(GPIO_PIN_08)//(Pin13)//(Pin08)
#define USART1_RX_GPIO_FUNC				(GPIO_FUNC_33)//(Func_Usart3_Rx)//(Func_Usart1_Rx)
/* USART TX Port/Pin definition */
#define USART1_TX_PORT					(GPIO_PORT_A)//(PortH)//(PortA)
#define USART1_TX_PIN					(GPIO_PIN_09)//(Pin02)//(Pin09)
#define USART1_TX_GPIO_FUNC				(GPIO_FUNC_32)//(Func_Usart3_Tx)//(Func_Usart1_Tx)

/**** USART interrupt definition***/
#define USART1_RX_ERR_IRQn               (INT003_IRQn)
#define USART1_RX_ERR_INT_SRC            (INT_SRC_USART1_EI)
#define USART1_RX_FULL_IRQn              (INT004_IRQn)
#define USART1_RX_FULL_INT_SRC           (INT_SRC_USART1_RI)
/* USART interrupt definition */
#define USART1_TX_CPLT_IRQn              (INT005_IRQn)
#define USART1_TX_CPLT_INT_SRC           (INT_SRC_USART1_TCI)

/***************************************usart3***************************************************/
/* USART unit definition */
#define USART3_UNIT                      (CM_USART3)
#define USART3_FCG_ENABLE()              (FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USART3, ENABLE))
/* UART RX/TX Port/Pin definition */
#define USART3_RX_PORT                   (GPIO_PORT_C)   /* PC13: USART3_RX */
#define USART3_RX_PIN                    (GPIO_PIN_13)
#define USART3_RX_GPIO_FUNC              (GPIO_FUNC_33)
/* USART TX Port/Pin definition */
#define USART3_TX_PORT                   (GPIO_PORT_H)   /* PH02: USART3_TX */
#define USART3_TX_PIN                    (GPIO_PIN_02)	
#define USART3_TX_GPIO_FUNC              (GPIO_FUNC_32)	

/**** USART interrupt definition***/
#define USART3_RX_ERR_IRQn               (INT000_IRQn)
#define USART3_RX_ERR_INT_SRC            (INT_SRC_USART3_EI)
#define USART3_RX_FULL_IRQn              (INT001_IRQn)
#define USART3_RX_FULL_INT_SRC           (INT_SRC_USART3_RI)

/* USART interrupt definition */
#define USART_TX_CPLT_IRQn              (INT002_IRQn)
#define USART_TX_CPLT_INT_SRC           (INT_SRC_USART3_TCI)

/***************************************end***************************************************/

static void USART_TxComplete_IrqCallback(void)
{
    USART_FuncCmd(USART3_UNIT, (USART_TX | USART_INT_TX_CPLT), DISABLE);
     //TMR0_Stop(TMR0_UNIT, TMR0_CH);
    USART_ClearStatus(USART3_UNIT, USART_FLAG_RX_TIMEOUT);
    USART_FuncCmd(USART3_UNIT, USART_RX_TIMEOUT, ENABLE);
    USART_ClearStatus(USART3_UNIT, USART_FLAG_TX_CPLT);
}

static void USART1_TxComplete_IrqCallback(void)
{
    USART_FuncCmd(USART1_UNIT, (USART_TX | USART_INT_TX_CPLT), DISABLE);
     //TMR0_Stop(TMR0_UNIT, TMR0_CH);
    USART_ClearStatus(USART1_UNIT, USART_FLAG_RX_TIMEOUT);
    USART_FuncCmd(USART1_UNIT, USART_RX_TIMEOUT, ENABLE);
    USART_ClearStatus(USART1_UNIT, USART_FLAG_TX_CPLT);
}
//串口模块配置
void Uart1_Config(CM_USART_TypeDef* USARTx ,uint32_t baud)
{
	stc_usart_uart_init_t stcUartInit; 
	stc_irq_signin_config_t stcIrqSigninConfig;

	/* Configure USART RX/TX pin. */
	GPIO_SetFunc(USART1_RX_PORT, USART1_RX_PIN, USART1_RX_GPIO_FUNC); 	
	GPIO_SetFunc(USART1_TX_PORT, USART1_TX_PIN, USART1_TX_GPIO_FUNC); 	
																		
	Dma1Init();				
	/* Enable peripheral clock */
	USART1_FCG_ENABLE(); 	
							
	/* Initialize UART.*/	
	(void)USART_UART_StructInit(&stcUartInit);
	stcUartInit.u32ClockDiv = USART_CLK_DIV64;
	stcUartInit.u32Baudrate = baud;
	stcUartInit.u32OverSampleBit = USART_OVER_SAMPLE_8BIT;
	if (LL_OK != USART_UART_Init(USARTx, &stcUartInit, NULL)) {
	for (;;) {
	}
	}

    /* Register TX complete IRQ handler. */
    stcIrqSigninConfig.enIRQn = USART1_TX_CPLT_IRQn;
    stcIrqSigninConfig.enIntSrc = USART1_TX_CPLT_INT_SRC;
    stcIrqSigninConfig.pfnCallback = &USART1_TxComplete_IrqCallback;
    (void)INTC_IrqSignIn(&stcIrqSigninConfig);
    NVIC_ClearPendingIRQ(stcIrqSigninConfig.enIRQn);
    NVIC_SetPriority(stcIrqSigninConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(stcIrqSigninConfig.enIRQn);
	
	/* Register RX error IRQ handler && configure NVIC. */
	stcIrqSigninConfig.enIRQn = USART1_RX_ERR_IRQn;
	stcIrqSigninConfig.enIntSrc = USART1_RX_ERR_INT_SRC;
	stcIrqSigninConfig.pfnCallback = &USART1_RxError_IrqCallback;
	INTC_IrqInstalHandler(&stcIrqSigninConfig, DDL_IRQ_PRIO_DEFAULT);

	/* Register RX full IRQ handler && configure NVIC. */
	stcIrqSigninConfig.enIRQn = USART1_RX_FULL_IRQn;
	stcIrqSigninConfig.enIntSrc = USART1_RX_FULL_INT_SRC;
	stcIrqSigninConfig.pfnCallback = &USART3_RxFull_IrqCallback;
	INTC_IrqInstalHandler(&stcIrqSigninConfig, DDL_IRQ_PRIO_DEFAULT);

	/* Enable RX/TX function */
	//USART_FuncCmd(USARTx, (USART_RX | USART_INT_RX | USART_TX), ENABLE);    
	USART_FuncCmd(USART1_UNIT, (USART_RX | USART_INT_RX | USART_RX_TIMEOUT | \
                               USART_INT_RX_TIMEOUT), ENABLE);
}


//串口模块配置
void Uart3_Config(CM_USART_TypeDef* USARTx ,uint32_t baud)
{
	stc_usart_uart_init_t stcUartInit;
	stc_irq_signin_config_t stcIrqSigninConfig;

	/* Configure USART RX/TX pin. */
	GPIO_SetFunc(USART3_RX_PORT, USART3_RX_PIN, USART3_RX_GPIO_FUNC);
	GPIO_SetFunc(USART3_TX_PORT, USART3_TX_PIN, USART3_TX_GPIO_FUNC);

	Dma2Init();
	/* Enable peripheral clock */
	USART3_FCG_ENABLE();

	/* Initialize UART. */
	(void)USART_UART_StructInit(&stcUartInit);
	stcUartInit.u32ClockDiv = USART_CLK_DIV64;
	stcUartInit.u32Baudrate = baud;
	stcUartInit.u32OverSampleBit = USART_OVER_SAMPLE_8BIT;
	if (LL_OK != USART_UART_Init(USARTx, &stcUartInit, NULL)) {
	for (;;) {
	}
	
	}
    /* Register TX complete IRQ handler. */
    stcIrqSigninConfig.enIRQn = USART_TX_CPLT_IRQn;
    stcIrqSigninConfig.enIntSrc = USART_TX_CPLT_INT_SRC;
    stcIrqSigninConfig.pfnCallback = &USART_TxComplete_IrqCallback;
    (void)INTC_IrqSignIn(&stcIrqSigninConfig);
    NVIC_ClearPendingIRQ(stcIrqSigninConfig.enIRQn);
    NVIC_SetPriority(stcIrqSigninConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(stcIrqSigninConfig.enIRQn);
	
	/* Register RX error IRQ handler && configure NVIC. */
	stcIrqSigninConfig.enIRQn = USART3_RX_ERR_IRQn;
	stcIrqSigninConfig.enIntSrc = USART3_RX_ERR_INT_SRC;
	stcIrqSigninConfig.pfnCallback = &USART3_RxError_IrqCallback;
	INTC_IrqInstalHandler(&stcIrqSigninConfig, DDL_IRQ_PRIO_DEFAULT);

	/* Register RX full IRQ handler && configure NVIC. */
	stcIrqSigninConfig.enIRQn = USART3_RX_FULL_IRQn;
	stcIrqSigninConfig.enIntSrc = USART3_RX_FULL_INT_SRC;
	stcIrqSigninConfig.pfnCallback = &USART_RxFull_IrqCallback;
	INTC_IrqInstalHandler(&stcIrqSigninConfig, DDL_IRQ_PRIO_DEFAULT);

	/* Enable RX/TX function */
    USART_FuncCmd(USART3_UNIT, (USART_RX | USART_INT_RX | USART_RX_TIMEOUT | \
                               USART_INT_RX_TIMEOUT), ENABLE);
	//USART_FuncCmd(USARTx, (USART_RX | USART_INT_RX | USART_TX), ENABLE);
}


int debug_Uart1_Init(void)//这个是有问题的
{
	Uart1_Config(USART1_UNIT,115200);
	return 0;
}
int debug_Uart3_Init(void)//这个是正常的
{
	Uart3_Config(USART3_UNIT,115200);
	return 0;
}

uint32_t Debug_Uart_SendDataPoll(uint8_t u8Data)
{
  uint16_t timeout;

  timeout = 0;

  while(++timeout<60000)
  {
    if(USART_GetStatus(USART3_UNIT, USART_FLAG_TX_EMPTY)) break;
  }
  USART_WriteData(USART3_UNIT, u8Data);
  timeout = 0;
  while(++timeout<60000)
  {
    if(USART_GetStatus(USART3_UNIT, USART_FLAG_TX_CPLT)) break;
  }
  return LL_OK;
}

void usart1Send(uint8_t* data,uint32_t size)
{
	for(uint32_t i=0;i<size;i++)
	{
		while (0u == USART_GetStatus(USART1_UNIT, USART_FLAG_TX_EMPTY))  /* Warit Tx data register empty */
		{	
		}	
		USART_WriteData(USART1_UNIT,data[i]);
	}
}
 
void usart3Send(uint8_t* data,uint32_t size)
{
	for(uint32_t i=0;i<size;i++)
	{
		while (0u == USART_GetStatus(USART3_UNIT, USART_FLAG_TX_EMPTY))  /* Warit Tx data register empty */
		{	
		}	
		USART_WriteData(USART3_UNIT,data[i]);
	}
}

/**
 * @brief  USART RX error IRQ callback.
 * @param  None
 * @retval None
 */
static void USART3_RxError_IrqCallback(void)
{
  if (SET == USART_GetStatus(USART3_UNIT, (USART_FLAG_PARITY_ERR | USART_FLAG_FRAME_ERR))) {
    (void)USART_ReadData(USART3_UNIT);
  }

  USART_ClearStatus(USART3_UNIT, (USART_FLAG_PARITY_ERR | USART_FLAG_FRAME_ERR | USART_FLAG_OVERRUN));
}

static void USART1_RxError_IrqCallback(void)
{
	//if (SET == USART_GetStatus(USART1_UNIT, (USART_FLAG_PARITY_ERR | USART_FLAG_FRAME_ERR))) 
	//{
		(void)USART_ReadData(USART1_UNIT);
	//}

  USART_ClearStatus(USART1_UNIT, (USART_FLAG_PARITY_ERR | USART_FLAG_FRAME_ERR | USART_FLAG_OVERRUN));
}
/**
 * @brief  USART RX IRQ callback
 * @param  None
 * @retval None
 */
static void USART_RxFull_IrqCallback(void)
{
  uint8_t u8Data = (uint8_t)USART_ReadData(CM_USART1);
  u8Data = u8Data;
}

static void USART3_RxFull_IrqCallback(void)
{
  uint8_t u8Data = (uint8_t)USART_ReadData(CM_USART3);
  u8Data = u8Data;
}


/**
 * @brief  Instal IRQ handler.
 * @param  [in] pstcConfig      Pointer to struct @ref stc_irq_signin_config_t
 * @param  [in] u32Priority     Interrupt priority
 * @retval None
 */
static void INTC_IrqInstalHandler(const stc_irq_signin_config_t *pstcConfig, uint32_t u32Priority)
{
  if (NULL != pstcConfig) {
    (void)INTC_IrqSignIn(pstcConfig);
    NVIC_ClearPendingIRQ(pstcConfig->enIRQn);
    NVIC_SetPriority(pstcConfig->enIRQn, u32Priority);
    NVIC_EnableIRQ(pstcConfig->enIRQn);
  }
}

